home *** CD-ROM | disk | FTP | other *** search
- /* ------------- editbox.c ------------ */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdlib.h>
- #include "dflat.h"
-
- #define EDITBUFFERLENGTH 4096
- #define ENTRYBUFFERLENGTH 1024
- #define GROWLENGTH 1024
-
-
- #define EditBufLen(wnd) (isMultiLine(wnd) ? EDITBUFFERLENGTH : ENTRYBUFFERLENGTH)
- #define WndCol (wnd->CurrCol-wnd->wleft)
- #define CurrChar (wnd->CurrLine+wnd->CurrCol)
-
- static void PasteText(WINDOW, char *, int);
- static void SaveDeletedText(WINDOW, char *, int);
- static void SetAnchor(WINDOW, int, int);
- static void Forward(WINDOW);
- static void Backward(WINDOW);
- static void End(WINDOW);
- static void Home(WINDOW);
- static void Downward(WINDOW);
- static void Upward(WINDOW);
- static char *FindLinePointer(WINDOW, int);
- static void StickEnd(WINDOW);
- static void UpLine(WINDOW);
- static void DownLine(WINDOW);
- static void NextWord(WINDOW);
- static void PrevWord(WINDOW);
- static void ResetEditBox(WINDOW);
- #define SetLinePointer(wnd, ln) (wnd->CurrLine = FindLinePointer(wnd, ln))
-
-
- static int KeyBoardMarking;
- int TextMarking;
- static int dragcount = -1;
-
- char *Clipboard;
- int ClipboardLength;
-
-
- int EditBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
- {
- int rtn;
- static int py = -1;
- int kx = (int) p1 - GetLeft(wnd);
- int ky = (int) p2 - GetTop(wnd);
- int c;
- RECT rc = ClientRect(wnd);
- char *lp;
- int len;
-
- int mx;
- int my;
-
- mx = (int) p1 - GetClientLeft(wnd) + wnd->wleft;
- my = (int) p2 - GetClientTop(wnd) + wnd->wtop;
- if (my < 0)
- my = 0;
-
- switch (msg) {
- case CREATE_WINDOW:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- wnd->text = malloc(EditBufLen(wnd));
- wnd->textlen = EditBufLen(wnd);
- ResetEditBox(wnd);
- return rtn;
- case ADDTEXT:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- if (!isMultiLine(wnd)) {
- wnd->CurrLine = wnd->text;
- wnd->CurrCol = strlen((char *)p1);
- if (wnd->CurrCol >= ClientWidth(wnd)) {
- wnd->wleft = wnd->CurrCol - ClientWidth(wnd);
- wnd->CurrCol -= wnd->wleft;
- }
- wnd->BlkEndCol = wnd->CurrCol;
- PostMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- }
- return rtn;
- case SETTEXT:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- wnd->CurrLine = wnd->text;
- return rtn;
- case CLEARTEXT:
- ResetEditBox(wnd);
- break;
- case EB_GETTEXT: {
- char *cp1 = (char *)p1;
- char *cp2 = wnd->text;
- while (p2-- && *cp2 && *cp2 != '\n')
- *cp1++ = *cp2++;
- *cp1 = '\0';
- return TRUE;
- }
- case EB_PUTTEXT:
- if (!isMultiLine(wnd)) {
- SendMessage(wnd, CLEARTEXT, 0, 0);
- SendMessage(wnd, ADDTEXT, p1, p2);
- }
- return TRUE;
- case SETFOCUS:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- if (p1) {
- SendMessage(NULLWND, SHOW_CURSOR, GetCommandToggle(ID_INSERT), 0);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- }
- else
- SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
- return rtn;
- case SHIFT_CHANGED:
- if (!(p1 & (LEFTSHIFT | RIGHTSHIFT)) && KeyBoardMarking) {
- SendMessage(wnd, BUTTON_RELEASED, 0, 0);
- KeyBoardMarking = FALSE;
- }
- break;
- case DOUBLE_CLICK:
- if (KeyBoardMarking)
- return TRUE;
- break;
- case LEFT_BUTTON:
- if (KeyBoardMarking || TextMarking)
- return TRUE;
- if (WindowMoving || WindowSizing)
- break;
- if (!InsideRect(p1, p2, rc))
- break;
-
- if (isMultiLine(wnd)) {
-
- if (BlockMarked(wnd)) {
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- }
-
- if (wnd->wlines) {
- if (my > wnd->wlines-1)
- break;
- lp = TextLine(wnd, my);
- len = (int) (strchr(lp, '\n') - lp);
- mx = min(mx, len);
- }
- else
- mx = my = 0;
-
- if (dragcount == -1)
- dragcount = 2;
- if (--dragcount == 0) {
- SetAnchor(wnd, mx, my);
- TextMarking = TRUE;
- SendMessage(wnd, CAPTURE_MOUSE, TRUE, 0);
- return TRUE;
- }
- wnd->WndRow = my-wnd->wtop;
- SetLinePointer(wnd, my);
- }
- if (isMultiLine(wnd) || !BlockMarked(wnd))
- wnd->CurrCol = wnd->wleft+mx;
- PostMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return TRUE;
- case MOUSE_MOVED:
- if (my > wnd->wlines-1)
- break;
- if (TextMarking && !(WindowMoving || WindowSizing)) {
- int ptop;
- int pbot;
- char *lp;
- int len;
- int y;
- int bbl, bel;
- RECT rc = ClientRect(wnd);
-
- if (!InsideRect(p1, p2, rc)) {
- if (p1 < GetClientLeft(wnd))
- p1 = GetClientLeft(wnd);
- if (p1 > GetClientRight(wnd))
- p1 = GetClientRight(wnd);
- if (p2 < GetClientTop(wnd))
- p2 = GetClientTop(wnd);
- if (p2 > GetClientBottom(wnd))
- p2 = GetClientBottom(wnd);
- SendMessage(NULLWND, MOUSE_CURSOR, p1, p2);
- }
-
- mx = (int) p1 - GetClientLeft(wnd);
- my = (int) p2 - GetClientTop(wnd);
-
- ptop = min(wnd->BlkBegLine, wnd->BlkEndLine);
- pbot = max(wnd->BlkBegLine, wnd->BlkEndLine);
-
- lp = TextLine(wnd, wnd->wtop+my);
- len = (int) (strchr(lp, '\n') - lp);
- mx = min(mx, len-wnd->wleft);
-
- wnd->BlkEndCol = mx+wnd->wleft;
- wnd->BlkEndLine = my+wnd->wtop;
-
- bbl = min(wnd->BlkBegLine, wnd->BlkEndLine);
- bel = max(wnd->BlkBegLine, wnd->BlkEndLine);
-
- while (ptop < bbl) {
- WriteTextLine(wnd, NULL, ptop-wnd->wtop, FALSE);
- ptop++;
- }
- for (y = bbl; y <= bel; y++)
- WriteTextLine(wnd, NULL, y-wnd->wtop, FALSE);
- while (pbot > bel) {
- WriteTextLine(wnd, NULL, pbot-wnd->wtop, FALSE);
- --pbot;
- }
- return FALSE;
- }
- break;
- case BUTTON_RELEASED:
- if (!isMultiLine(wnd))
- break;
- dragcount = -1;
- if (TextMarking && !(WindowMoving || WindowSizing)) {
- PostMessage(wnd, RELEASE_MOUSE, 0, 0);
- TextMarking = FALSE;
- if (wnd->BlkBegLine > wnd->BlkEndLine) {
- swap(wnd->BlkBegLine, wnd->BlkEndLine);
- swap(wnd->BlkBegCol, wnd->BlkEndCol);
- }
- if (wnd->BlkBegLine == wnd->BlkEndLine &&
- wnd->BlkBegCol > wnd->BlkEndCol)
- swap(wnd->BlkBegCol, wnd->BlkEndCol);
- return TRUE;
- }
- else
- py = -1;
- break;
- case SCROLL:
- if (!isMultiLine(wnd))
- break;
- if ((rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2)) != FALSE) {
- if (p1) {
- /* -------- scrolling up --------- */
- if (wnd->WndRow == 0) {
- DownLine(wnd);
- StickEnd(wnd);
- }
- else
- --wnd->WndRow;
- }
- else {
- /* -------- scrolling down --------- */
- if (wnd->WndRow == ClientHeight(wnd)-1) {
- UpLine(wnd);
- StickEnd(wnd);
- }
- else
- wnd->WndRow++;
- }
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- }
- return rtn;
- case HORIZSCROLL:
- if (p1 && wnd->CurrCol == wnd->wleft &&
- *CurrChar == '\n')
- return FALSE;
- if ((rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2)) != FALSE) {
- if (wnd->CurrCol < wnd->wleft)
- wnd->CurrCol++;
- else if (WndCol == ClientWidth(wnd))
- --wnd->CurrCol;
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- }
- return rtn;
- case MOVE:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return rtn;
- case SIZE:
- rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- if (WndCol > ClientWidth(wnd)-1)
- wnd->CurrCol = ClientWidth(wnd)-1 + wnd->wleft;
- if (wnd->WndRow > ClientHeight(wnd)-1) {
- wnd->WndRow = ClientHeight(wnd)-1;
- SetLinePointer(wnd, wnd->WndRow+wnd->wtop);
- }
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return rtn;
- case KEYBOARD:
- if (WindowMoving || WindowSizing)
- break;
- c = (int) p1;
- if ((p2 & ALTKEY) ||
- c == SHIFT_INS || c == SHIFT_DEL)
- break;
- if ((p2 & CTRLKEY) && c != CTRL_FWD &&
- c != CTRL_BS &&
- c != CTRL_HOME &&
- c != CTRL_END)
- break;
- if (c == ESC)
- break;
- if (isMultiLine(wnd)) {
- if (p2 & (LEFTSHIFT | RIGHTSHIFT)) {
- SendMessage(NULLWND, CURRENT_KEYBOARD_CURSOR,
- (PARAM) &kx, (PARAM)&ky);
-
- kx -= GetClientLeft(wnd);
- ky -= GetClientTop(wnd);
-
- switch (c) {
- case HOME:
- case END:
- case PGUP:
- case PGDN:
- case UP:
- case DN:
- case FWD:
- case BS:
- case CTRL_FWD:
- case CTRL_BS:
- if (!KeyBoardMarking) {
- if (BlockMarked(wnd)) {
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- }
- KeyBoardMarking = TextMarking = TRUE;
- SetAnchor(wnd, kx+wnd->wleft, ky+wnd->wtop);
- }
- break;
- default:
- break;
- }
- }
- else if (((c != DEL && c != RUBOUT) ||
- !isMultiLine(wnd)) && BlockMarked(wnd)) {
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
- switch (c) {
- case PGUP:
- case PGDN:
- if (!isMultiLine(wnd))
- break;
- BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- SetLinePointer(wnd, wnd->wtop+wnd->WndRow);
- StickEnd(wnd);
- SendMessage(wnd, KEYBOARD_CURSOR,WndCol, wnd->WndRow);
- break;
- case HOME:
- Home(wnd);
- break;
- case END:
- End(wnd);
- break;
- case CTRL_FWD:
- NextWord(wnd);
- break;
- case CTRL_BS:
- PrevWord(wnd);
- break;
- case CTRL_HOME:
- if (!isMultiLine(wnd)) {
- Home(wnd);
- break;
- }
- rtn = BaseWndProc(EDITBOX, wnd, msg, HOME, p2);
- Home(wnd);
- wnd->CurrLine = wnd->text;
- wnd->WndRow = 0;
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return rtn;
- case CTRL_END:
- if (!isMultiLine(wnd)) {
- End(wnd);
- break;
- }
- Home(wnd);
- rtn = BaseWndProc(EDITBOX, wnd, msg, END, p2);
- SetLinePointer(wnd, wnd->wlines-1);
- wnd->WndRow = min(ClientHeight(wnd)-1, wnd->wlines-1);
- End(wnd);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return rtn;
- case UP:
- if (!isMultiLine(wnd))
- break;
- Upward(wnd);
- break;
- case DN:
- if (!isMultiLine(wnd))
- break;
- Downward(wnd);
- break;
- case FWD:
- Forward(wnd);
- break;
- case BS:
- Backward(wnd);
- break;
- }
- if (KeyBoardMarking) {
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- SendMessage(NULLWND, CURRENT_KEYBOARD_CURSOR,
- (PARAM) &kx, (PARAM)&ky);
- SendMessage(wnd, MOUSE_MOVED, kx, ky);
- return TRUE;
- }
- if (!TestAttribute(wnd, READONLY)) {
- switch (c) {
- case HOME:
- case END:
- case PGUP:
- case PGDN:
- case UP:
- case DN:
- case FWD:
- case BS:
- case CTRL_FWD:
- case CTRL_BS:
- case CTRL_HOME:
- case CTRL_END:
- case RUBOUT:
- if (!isMultiLine(wnd) && BlockMarked(wnd)) {
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- }
- if (c != RUBOUT)
- break;
- if (wnd->CurrLine == wnd->text && wnd->CurrCol == 0)
- break;
- Backward(wnd);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- case DEL:
- if (BlockMarked(wnd)) {
- SendMessage(wnd, COMMAND, ID_DELETETEXT, 0);
- return TRUE;
- }
- if (*(CurrChar+1) == '\0')
- return TRUE;
- if (isMultiLine(wnd) &&
- *CurrChar == '\n')
- --wnd->wlines;
- if (*(CurrChar+1)) {
- int repaint = *CurrChar == '\n';
- strcpy(CurrChar, CurrChar+1);
- if (repaint)
- SendMessage(wnd, PAINT, 0, 0);
- else
- WriteTextLine(wnd, NULL, wnd->WndRow, FALSE);
- }
- wnd->TextChanged = TRUE;
- break;
- case INS:
- InvertCommandToggle(ID_INSERT);
- SendMessage(NULLWND, SHOW_CURSOR, GetCommandToggle(ID_INSERT), 0);
- break;
- case '\r':
- if (isMultiLine(wnd))
- c = '\n';
- default:
- if (c == '\t') {
- int insmd = GetCommandToggle(ID_INSERT);
- if (!isMultiLine(wnd))
- PostMessage(GetParent(wnd), msg, p1, p2);
- else do {
- if (!insmd && *(CurrChar+1) == '\0')
- break;
- SendMessage(wnd, KEYBOARD,
- insmd ? ' ' : FWD, 0);
- } while (wnd->CurrCol % cfg.Tabs);
- return TRUE;
- }
- if ((c != '\n' && c < ' ') || (c & 0x1000))
- /* ---- not recognized by editor --- */
- break;
- if (!isMultiLine(wnd) && BlockMarked(wnd)) {
- ResetEditBox(wnd);
- ClearBlock(wnd);
- }
- if (*CurrChar == '\0') {
- *CurrChar = '\n';
- *(CurrChar+1) = '\0';
- wnd->wlines++;
- }
- /* --- displayable char or newline --- */
- if (c == '\n' ||
- GetCommandToggle(ID_INSERT) ||
- *CurrChar == '\n') {
- char *cp = wnd->CurrLine;
- while (*cp && *cp != '\n')
- cp++;
- wnd->textwidth = max(wnd->textwidth,
- (int) (cp-wnd->CurrLine+1));
- /* ------ insert mode ------ */
- memmove(CurrChar+1, CurrChar, strlen(CurrChar)+1);
- WriteTextLine(wnd, NULL, wnd->WndRow, FALSE);
- if (strlen(wnd->text) == wnd->textlen) {
- int dif = (int) (wnd->CurrLine - wnd->text);
- wnd->textlen += GROWLENGTH;
- wnd->text = realloc(wnd->text, wnd->textlen);
- wnd->CurrLine = wnd->text + dif;
- }
- }
- /* ----- put the char in the buffer ----- */
- *CurrChar = c;
- wnd->TextChanged = TRUE;
- if (c == '\n') {
- wnd->wleft = 0;
- wnd->wlines++;
- End(wnd);
- Forward(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- break;
- }
- /* ---------- test end of window --------- */
- if (WndCol == ClientWidth(wnd)-1) {
- int dif;
- char *cp = CurrChar;
- while (*cp != ' ' && cp != wnd->CurrLine)
- --cp;
- if (!isMultiLine(wnd) || cp == wnd->CurrLine ||
- !GetCommandToggle(ID_WRAP))
- SendMessage(wnd, HORIZSCROLL, TRUE, 0);
- else {
- dif = 0;
- if (c != ' ') {
- dif = (int) (CurrChar - cp);
- wnd->CurrCol -= dif;
- SendMessage(wnd, KEYBOARD, DEL, 0);
- --dif;
- }
- SendMessage(wnd, KEYBOARD, '\r', 0);
- wnd->CurrCol = dif;
- if (c == ' ')
- break;
- }
- }
- /* ------ display the character ------ */
- SetStandardColor(wnd);
- PutWindowChar(wnd, WndCol, wnd->WndRow, c);
- /* ----- advance the pointers ------ */
- wnd->CurrCol++;
- break;
- }
- }
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- return TRUE;
- case COMMAND: {
- char *bbl, *bel, *bb;
- int len;
-
- if (BlockMarked(wnd)) {
- bbl = FindLinePointer(wnd, wnd->BlkBegLine) + wnd->BlkBegCol;
- bel = FindLinePointer(wnd, wnd->BlkEndLine) + wnd->BlkEndCol;
- len = (int) (bel - bbl);
- }
- switch ((int)p1) {
- case ID_CUT:
- case ID_COPY:
- ClipboardLength = len;
- Clipboard = realloc(Clipboard, ClipboardLength);
- if (Clipboard != NULL)
- memmove(Clipboard, bbl, ClipboardLength);
- case ID_DELETETEXT:
- if (p1 != ID_COPY) {
- if (p1 != ID_CUT)
- SaveDeletedText(wnd, bbl, len);
- wnd->TextChanged = TRUE;
- strcpy(bbl, bel);
- wnd->CurrLine = bbl - wnd->BlkBegCol;
- wnd->CurrCol = wnd->BlkBegCol;
- wnd->WndRow = wnd->BlkBegLine - wnd->wtop;
- if (wnd->WndRow < 0) {
- wnd->wtop = wnd->BlkBegLine;
- wnd->WndRow = 0;
- }
- wnd->wlines -= wnd->BlkEndLine - wnd-> BlkBegLine;
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- }
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- return TRUE;
- case ID_CLEAR:
- SaveDeletedText(wnd, bbl, len);
- wnd->CurrLine = bbl;
- wnd->CurrCol = wnd->BlkBegCol;
- wnd->WndRow = wnd->BlkBegLine - wnd->wtop;
- if (wnd->WndRow < 0) {
- wnd->WndRow = 0;
- wnd->wtop = wnd->BlkBegLine;
- }
- while (bbl < bel) {
- char *cp = strchr(bbl, '\n');
- if (cp > bel)
- cp = bel;
- strcpy(bbl, cp);
- bel -= (int) (cp - bbl);
- bbl++;
- }
- ClearBlock(wnd);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- SendMessage(wnd, PAINT, 0, 0);
- wnd->TextChanged = TRUE;
- return TRUE;
- case ID_PASTE:
- if (Clipboard != NULL) {
- PasteText(wnd, Clipboard, ClipboardLength);
- wnd->TextChanged = TRUE;
- }
- return TRUE;
- case ID_UNDO:
- if (wnd->DeletedText != NULL) {
- PasteText(wnd, wnd->DeletedText, wnd->DeletedLength);
- free(wnd->DeletedText);
- wnd->DeletedText = NULL;
- }
- return TRUE;
- case ID_PARAGRAPH: {
- char *bl;
- int bc, ec;
- int fl, el;
- int Blocked;
-
- el = wnd->BlkEndLine;
- ec = wnd->BlkEndCol;
- if (!BlockMarked(wnd)) {
- Blocked = FALSE;
- /* ---- forming paragraph from cursor position --- */
- fl = wnd->wtop + wnd->WndRow;
- bl = wnd->CurrLine;
- bc = wnd->CurrCol;
- Home(wnd);
- bbl = bel = bl;
- if (bc >= ClientWidth(wnd))
- bc = 0;
- /* ---- locate the end of the paragraph ---- */
- while (*bel) {
- int blank = TRUE;
- char *bll = bel;
- /* --- blank line marks end of paragraph --- */
- while (*bel && *bel != '\n') {
- if (*bel != ' ')
- blank = FALSE;
- bel++;
- }
- if (blank) {
- bel = bll;
- break;
- }
- if (*bel)
- bel++;
- }
- if (bel == bbl) {
- SendMessage(wnd, KEYBOARD, DN, 0);
- return TRUE;
- }
- if (*bel == '\0')
- --bel;
- if (*bel == '\n')
- --bel;
- }
- else {
- Blocked = TRUE;
- /* ---- forming paragraph from marked block --- */
- fl = wnd->BlkBegLine;
- bc = wnd->CurrCol = wnd->BlkBegCol;
- wnd->CurrLine = FindLinePointer(wnd, fl);
- if (fl < wnd->wtop)
- wnd->wtop = fl;
- wnd->WndRow = fl - wnd->wtop;
- SendMessage(wnd, KEYBOARD, '\r', 0);
- el++, fl++;
- if (bc != 0) {
- SendMessage(wnd, KEYBOARD, '\r', 0);
- el++, fl ++;
- }
- bc = 0;
- bl = wnd->CurrLine = FindLinePointer(wnd, fl);
- bbl = bl + bc;
- bel = FindLinePointer(wnd, el) + ec;
- }
-
- /* --- change all newlines in block to spaces --- */
- while (CurrChar < bel) {
- if (*CurrChar == '\n') {
- *CurrChar = ' ';
- wnd->CurrLine = CurrChar + 1;
- wnd->CurrCol = 0;
- --wnd->wlines;
- }
- else
- wnd->CurrCol++;
- }
-
- /* ---- insert newlines at new margin boundaries ---- */
- bb = bbl;
- while (bbl < bel) {
- bbl++;
- if ((int)(bbl - bb) == ClientWidth(wnd)-1) {
- while (*bbl != ' ' && bbl > bb)
- --bbl;
- if (*bbl != ' ') {
- bbl = strchr(bbl, ' ');
- if (bbl == NULL || bbl >= bel)
- break;
- }
- *bbl = '\n';
- wnd->textwidth = max(wnd->textwidth,
- (int) (bbl-bb));
- wnd->wlines++;
- bb = bbl+1;
- }
- }
- ec = (int)(bel - bb);
-
- if (Blocked) {
- /* ---- position cursor at end of new paragraph ---- */
- if (el < wnd->wtop ||
- wnd->wtop + ClientHeight(wnd) < el)
- wnd->wtop = el-ClientHeight(wnd);
- if (wnd->wtop < 0)
- wnd->wtop = 0;
- wnd->WndRow = el - wnd->wtop;
- wnd->CurrLine = FindLinePointer(wnd, el);
- wnd->CurrCol = ec;
- SendMessage(wnd, KEYBOARD, '\r', 0);
- SendMessage(wnd, KEYBOARD, '\r', 0);
- }
- else {
- /* --- put cursor back at beginning --- */
- wnd->CurrLine = bl;
- wnd->CurrCol = bc;
- if (fl < wnd->wtop)
- wnd->wtop = fl;
- wnd->WndRow = fl - wnd->wtop;
- }
- SendMessage(wnd, PAINT, 0, 0);
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- wnd->TextChanged = TRUE;
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- case CLOSE_WINDOW:
- SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
- if (wnd->DeletedText != NULL)
- free(wnd->DeletedText);
- break;
- default:
- break;
- }
- return BaseWndProc(EDITBOX, wnd, msg, p1, p2);
- }
-
- static void PasteText(WINDOW wnd, char *SaveTo, int len)
- {
- int plen = strlen(wnd->text) + len + 1;
- char *bl = CurrChar;
- char *el = bl+len;
- if (plen > wnd->textlen) {
- wnd->text = realloc(wnd->text, plen);
- wnd->textlen = plen;
- }
- memmove(el, bl, strlen(bl)+1);
- memmove(bl, SaveTo, len);
- while (bl < el)
- if (*bl++ == '\n')
- wnd->wlines++;
- SendMessage(wnd, PAINT, 0, 0);
- }
-
- static void SaveDeletedText(WINDOW wnd, char *bbl, int len)
- {
- wnd->DeletedLength = len;
- if ((wnd->DeletedText = realloc(wnd->DeletedText, len)) != NULL)
- memmove(wnd->DeletedText, bbl, len);
- }
-
- static void SetAnchor(WINDOW wnd, int mx, int my)
- {
- if (BlockMarked(wnd)) {
- ClearBlock(wnd);
- SendMessage(wnd, PAINT, 0, 0);
- }
- dragcount = -1;
- /* ------ set the anchor ------ */
- wnd->BlkBegLine = wnd->BlkEndLine = my;
- wnd->BlkBegCol = wnd->BlkEndCol = mx;
- WriteTextLine(wnd, NULL, my, FALSE);
- }
-
- static void Forward(WINDOW wnd)
- {
- if (*(CurrChar+1) == '\0')
- return;
- if (*CurrChar == '\n') {
- Home(wnd);
- Downward(wnd);
- }
- else {
- wnd->CurrCol++;
- if (WndCol == ClientWidth(wnd)) {
- wnd->wleft++;
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
- }
-
- static void StickEnd(WINDOW wnd)
- {
- int len = (int) (strchr(wnd->CurrLine, '\n') - wnd->CurrLine);
-
- wnd->CurrCol = min(len, wnd->CurrCol);
- if (wnd->wleft > wnd->CurrCol) {
- wnd->wleft = max(0, wnd->CurrCol - 4);
- SendMessage(wnd, PAINT, 0, 0);
- }
- else if (wnd->CurrCol-wnd->wleft >= ClientWidth(wnd)) {
- wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1);
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
-
- static void Downward(WINDOW wnd)
- {
- if (isMultiLine(wnd) && wnd->WndRow+wnd->wtop+1 < wnd->wlines) {
- DownLine(wnd);
- if (wnd->WndRow == ClientHeight(wnd)-1) {
- if (wnd->wtop+ClientHeight(wnd) <= wnd->wlines) {
- wnd->wtop++;
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
- else
- wnd->WndRow++;
- StickEnd(wnd);
- }
- }
-
- static void DownLine(WINDOW wnd)
- {
- wnd->CurrLine = strchr(wnd->CurrLine, '\n');
- wnd->CurrLine++;
- }
-
- static void UpLine(WINDOW wnd)
- {
- --wnd->CurrLine;
- if (wnd->CurrLine != wnd->text) {
- --wnd->CurrLine;
- while (wnd->CurrLine != wnd->text && *wnd->CurrLine != '\n')
- --wnd->CurrLine;
- if (*wnd->CurrLine == '\n')
- wnd->CurrLine++;
- }
- }
-
- static void Upward(WINDOW wnd)
- {
- if (isMultiLine(wnd) && wnd->CurrLine != wnd->text) {
- UpLine(wnd);
- if (wnd->WndRow == 0) {
- if (wnd->wtop) {
- --wnd->wtop;
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
- else
- --wnd->WndRow;
- StickEnd(wnd);
- }
- }
-
- static void Backward(WINDOW wnd)
- {
- if (wnd->CurrCol) {
- if (wnd->CurrCol-- <= wnd->wleft) {
- if (wnd->wleft != 0) {
- --wnd->wleft;
- SendMessage(wnd, PAINT, 0, 0);
- return;
- }
- }
- else
- return ;
- }
- if (isMultiLine(wnd) && wnd->CurrLine != wnd->text) {
- Upward(wnd);
- End(wnd);
- }
- }
-
- static void End(WINDOW wnd)
- {
- while (*CurrChar != '\n')
- ++wnd->CurrCol;
- if (WndCol >= ClientWidth(wnd)) {
- wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1);
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
-
- static void Home(WINDOW wnd)
- {
- wnd->CurrCol = 0;
- if (wnd->wleft != 0) {
- wnd->wleft = 0;
- SendMessage(wnd, PAINT, 0, 0);
- }
- }
-
- static char *FindLinePointer(WINDOW wnd, int ln)
- {
- char *cp = wnd->text;
- while (ln--) {
- cp = strchr(cp, '\n');
- cp++;
- }
- return cp;
- }
-
- #define isWhite(c) ((c) == ' ' || (c) == '\n')
-
- static void NextWord(WINDOW wnd)
- {
- int savetop = wnd->wtop;
- int saveleft = wnd->wleft;
- ClearVisible(wnd);
- while (!isWhite(*CurrChar)) {
- if (*(CurrChar+1) == '\0')
- break;
- Forward(wnd);
- }
- while (isWhite(*CurrChar)) {
- if (*(CurrChar+1) == '\0')
- break;
- Forward(wnd);
- }
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- SetVisible(wnd);
- if (wnd->wtop != savetop || wnd->wleft != saveleft)
- SendMessage(wnd, PAINT, 0, 0);
- }
-
- static void PrevWord(WINDOW wnd)
- {
- int savetop = wnd->wtop;
- int saveleft = wnd->wleft;
- ClearVisible(wnd);
- Backward(wnd);
- while (isWhite(*CurrChar)) {
- if (wnd->CurrLine == wnd->text && wnd->CurrCol == 0)
- break;
- Backward(wnd);
- }
- while (!isWhite(*CurrChar)) {
- if (wnd->CurrLine == wnd->text && wnd->CurrCol == 0)
- break;
- Backward(wnd);
- }
- if (isWhite(*CurrChar))
- Forward(wnd);
- if (wnd->wleft != saveleft)
- if (wnd->CurrCol >= saveleft)
- if (wnd->CurrCol - saveleft < ClientWidth(wnd))
- wnd->wleft = saveleft;
- SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
- SetVisible(wnd);
- if (wnd->wtop != savetop || wnd->wleft != saveleft)
- SendMessage(wnd, PAINT, 0, 0);
- }
-
- static void ResetEditBox(WINDOW wnd)
- {
- *wnd->text = '\0';
- wnd->wlines = 0;
- wnd->CurrLine = wnd->text;
- wnd->CurrCol = 0;
- wnd->WndRow = 0;
- wnd->TextChanged = FALSE;
- wnd->wleft = 0;
- }
-